package com.school.controller.admin;


import com.github.pagehelper.PageInfo;
import com.school.dto.AdvancedLikes;
import com.school.dto.LikeWithUser;
import com.school.dto.SimplePage;
import com.school.dto.SimpleUserLikes;
import com.school.exception.LikesAlreadyExistException;
import com.school.exception.UserNotFoundException;
import com.school.model.Likes;
import com.school.model.Sign;
import com.school.model.User;
import com.school.service.impl.EmailServiceImpl;
import com.school.service.impl.LikeServiceImpl;
import com.school.service.impl.SignServiceImpl;
import com.school.service.impl.UserServiceImpl;
import com.school.utils.ResponseUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.mail.MailException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

@RestController("adminLikeController")
@RequestMapping({"/api/admin/like"})
@Api(
        value = "签约意向管理",
        tags = {"签约意向管理"}
)
public class AdminLikeController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private LikeServiceImpl likeService;
    @Autowired
    private UserServiceImpl userService;
    @Autowired
    private EmailServiceImpl emailService;
    @Autowired
    private SignServiceImpl signService;


    @GetMapping({"/listSearchSingle"})
    @ApiOperation(
            value = "查看单项意向，搜索/分页显示",
            notes = "输入高校名进行搜索"
    )
//    @PreAuthorize("hasRole('ADMINISTRATOR')")
    public Object searchSingle(@RequestParam(value = "schoolname", required = false) String likeSchoolName,
                               @ApiParam(example = "1", value = "分页使用，要第几页的数据") @RequestParam(required = false) Integer page,
                               @ApiParam(example = "10", value = "分页使用，要该页的几条数据") @RequestParam(required = false) Integer pageSize,
                               @ApiParam(example = "1", value = "排序方式，从数据库中要的数据使用什么进行排序，如 add_time,update_time") @RequestParam(defaultValue = "add_time", required = false) String sort,
                               @ApiParam(example = "desc", value = "排序方式，升序asc还是降序desc") @RequestParam(defaultValue = "desc", required = false) String order,
                               @ApiParam(example = "2020", value = "year") @RequestParam(required = false, value = "year") Integer year) {
        PageInfo likeWithUserPageInfo = this.likeService.querySelective(year, likeSchoolName, page, pageSize, sort, order);
        int count = likeService.count(year, likeSchoolName);
        SimplePage<List<LikeWithUser>> listSimplePage = new SimplePage<List<LikeWithUser>>(count, likeWithUserPageInfo.getList());
        return ResponseUtil.build(HttpStatus.OK.value(), "获取单项意向表 成功！", listSimplePage);
    }


    @GetMapping({"/listSearch"})
    @ApiOperation(
            value = "搜索/分页显示",
            notes = "输入高校名进行搜索"
    )
    @PreAuthorize("hasRole('ADMINISTRATOR')")
    public Object search(@RequestParam(value = "schoolname", required = false) String likeSchoolName,
                         @ApiParam(example = "1", value = "分页使用，要第几页的数据") @RequestParam(required = false) Integer page,
                         @ApiParam(example = "10", value = "分页使用，要该页的几条数据") @RequestParam(required = false) Integer pageSize,
                         @ApiParam(example = "1", value = "排序方式，从数据库中要的数据使用什么进行排序，如 add_time,update_time") @RequestParam(defaultValue = "add_time", required = false) String sort,
                         @ApiParam(example = "desc", value = "排序方式，升序asc还是降序desc") @RequestParam(defaultValue = "desc", required = false) String order,
                         @ApiParam(example = "2020", value = "year") @RequestParam(defaultValue = "2020", required = false) Integer year) {
        List<Likes> likesList = this.likeService.querySelectiveDistinct(year, likeSchoolName, page, pageSize, sort, order);
        int count = this.likeService.countDistinct(year, likeSchoolName);
        List<AdvancedLikes> advancedLikes = likeService.retrieveAdvancedLikes(likesList);
        SimplePage<List<AdvancedLikes>> listSimplePage = new SimplePage<>(count, advancedLikes);
        return ResponseUtil.build(HttpStatus.OK.value(), "获取签约结果意向表表成功！", listSimplePage);
    }

    @ApiOperation(
            value = "导出单项签约意向表",
            notes = "导出单项签约意向表"
    )
    @PreAuthorize("hasRole('ADMINISTRATOR')")
    @GetMapping({"/exportLikesFormSingle"})
    public void exportLikesFormSingle(@ApiParam(example = "意向的的ids", value = "[1,2,3]") @RequestParam(required = false, value = "likeIds") Integer[] likeIds, HttpServletResponse response) throws IOException {
        List<Likes> likesList = null;
        if (likeIds == null || likeIds.length == 0) {
            PageInfo pageInfo = likeService.querySelective();
            likesList = pageInfo.getList();
        } else {
            likesList = new LinkedList<>();
            for (Integer likeId : likeIds) {
                likesList.addAll(likeService.queryById(likeId));
            }
        }
        Workbook workbook = this.likeService.exportLikesFormSingle(likesList);
        String fileName = Likes.class.getSimpleName() + ".xls";
        response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
        workbook.write(outputStream);
        outputStream.close();
        workbook.close();
    }

    @ApiOperation(
            value = "导出签约意向表",
            notes = "导出签约意向表"
    )
    @PreAuthorize("hasRole('ADMINISTRATOR')")
    @GetMapping({"/exportLikesForm"})
    public void exportLikesForm(@ApiParam(example = "用户的的的ids", value = "[1,2,3]") @RequestParam(required = false, value = "userIds") Integer[] userIds, HttpServletResponse response) throws IOException {
        List<Likes> likesList;
        if (userIds == null || userIds.length == 0) {
            likesList = likeService.querySelective().getList();
        } else {
            likesList = new LinkedList<>();
            for (Integer userId : userIds) {
                likesList.addAll(likeService.queryByLikeUserId(userId));
            }
        }
        Workbook workbook = this.likeService.exportLikesForm(likesList);
        String fileName = Likes.class.getSimpleName() + ".xls";
        response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
        workbook.write(outputStream);
        outputStream.close();
        workbook.close();
    }

    @GetMapping({"/list/{userId}"})
    @ApiOperation(
            value = "凭每个高校id查看",
            notes = "每个高校的意向的查看"
    )
    @PreAuthorize("hasRole('ADMINISTRATOR')")
    public Object list(@PathVariable("userId") Integer likeUserId) {
        PageInfo<Likes> pageInfo = this.likeService.querySelective(null, likeUserId);
        List<Likes> likes = pageInfo.getList();
        SimpleUserLikes simpleUserLikes = new SimpleUserLikes();
        List<Likes> likesList = new LinkedList<>();
        for (Likes like : likes) {
            if (simpleUserLikes.getUserId() == null) {
                simpleUserLikes.setUserId(like.getLikeUserId());
            }
            like.setLikeUserId(null);
            like.setAddTime(null);
            like.setUpdateTime(null);
            like.setDeleted(null);
            likesList.add(like);
        }
        simpleUserLikes.setLikes(likesList);
        return ResponseUtil.build(HttpStatus.OK.value(), "获取该学校的所有意向成功！", simpleUserLikes);
    }


    @PostMapping({"/batchLikes"})
    @ApiOperation(
            value = "批量添加意向",
            notes = "批量添加多则意向"
    )
//    @PreAuthorize("hasRole('ADMINISTRATOR')")
    public String add(
            @ApiParam(example = "1", value = "主动去喜欢其他用户的用户", required = true) @RequestParam("likeUserId") Integer likeUserId,
            @ApiParam(example = "2", value = "被喜欢的用户的id", required = true) @RequestParam("likedUserIds") Integer[] likedUserIds) throws UserNotFoundException {
        User likeUser = this.userService.queryById(likeUserId);
        if (likeUser == null) {
            throw new UserNotFoundException("用户id不存在！");
        }
        for (Integer likedUserId : likedUserIds) {
            //异常判断全由service来做，除了查询的
            Likes like = new Likes();
            like.setLikeUserId(likeUser.getId());
            like.setLikedUserId(likedUserId);
            try {
                this.likeService.add(like);
            } catch (LikesAlreadyExistException | UserNotFoundException e) {
                logger.error("用户id不存在！");
                continue;
            }
            checkIfNeedSign(like);
        }
        return ResponseUtil.build(HttpStatus.OK.value(), "管理端添加该学校意向成功！");
    }

    //TODO
    private void checkIfNeedSign(Likes like) {
        Integer likeUserId = like.getLikeUserId();
        Integer likedUserId = like.getLikedUserId();
        PageInfo<Likes> pageInfo = likeService.querySelective(likedUserId, likeUserId);
        List<Likes> likesList = pageInfo.getList();
        //如果没有用户对该用户表明过意向，直接跳过
        if (likesList==null||likesList.size() == 0) {
            return;
        }
        Likes likes1 = likesList.get(0);
        if (likes1.getSigned().equals((byte) 1)) {
            //已经签约过了
            return;
        }
        //若数据库中能查到该则意向的相反意向，证明该则意向匹配，自动签约
        likes1.setSigned((byte) 1);
        likeService.updateByIdSelective(likes1);
        Sign sign = new Sign();
        sign.setSignUserId(like.getLikeUserId());
        sign.setSignedUserId(like.getLikedUserId());
        signService.add(sign);
    }

    @DeleteMapping({"/delete"})
    @ApiOperation(
            value = "签约意向管理->修改签约意向-批量删除()",
            notes = "签约意向管理->修改签约意向-批量删除()"
    )
    @PreAuthorize("hasRole('ADMINISTRATOR')")
    public Object delete(@ApiParam(example = "1", value = "意向的id->数组") @RequestParam("ids") Integer[] ids) {
        for (Integer i : ids) {
            this.likeService.deleteById(i);
        }
        return ResponseUtil.build(HttpStatus.OK.value(), "删除多则意向成功！", (Object) null);
    }

    @ApiOperation(
            value = "签约意向管理->发送消息提醒高校参与意向选择",
            notes = "签约意向管理->发送消息提醒高校参与意向选择"
    )
    @PreAuthorize("hasRole('ADMINISTRATOR')")
    @PostMapping({"/remind"})
    public String remindSchools(@ApiParam(example = "用户id数组", value = "[1,2,3]") @RequestParam(value = "userIds", required = false) Integer[] userIds) {
        List<User> users = null;
        if (userIds == null || userIds.length != 0) {
            PageInfo<User> userPageInfo = userService.querySelective();
            users = userPageInfo.getList();
        } else {
            users = new LinkedList<>();
            for (Integer userId : userIds) {
                User user = userService.queryById(userId);
                users.add(user);
            }
        }
        List<User> finalUsers = users;
        new Thread(() -> {
            Iterator var2 = finalUsers.iterator();
            while (var2.hasNext()) {
                User user = (User) var2.next();
                try {
                    this.emailService.send(user.getUsername(), "!签约意向提醒!", "时间马上就要截至了,记得来参与意向选择~");
                } catch (MailException var5) {
                    this.logger.warn("该邮箱号不存在:" + user.getUsername());
                }
            }
        }).start();
        return ResponseUtil.build(HttpStatus.OK.value(), "签约意向提醒成功!");
    }

    @PreAuthorize("hasRole('ADMINISTRATOR')")
    @GetMapping({"/listSchools"})
    @ApiOperation(
            value = "签约意向管理->修改签约意向->添加意向高校->输入高校名搜索",
            notes = "签约意向管理->修改签约意向->添加意向高校->输入高校名搜索"
    )
    public Object listSchools(@RequestParam(value = "schoolName", required = false) String schoolName, @ApiParam(example = "1", value = "分页使用，要第几页的数据") @RequestParam(required = false) Integer page, @ApiParam(example = "10", value = "分页使用，要该页的几条数据") @RequestParam(required = false) Integer pageSize, @ApiParam(example = "1", value = "排序方式，从数据库中要的数据使用什么进行排序，如 add_time,update_time") @RequestParam(defaultValue = "add_time", required = false) String sort, @ApiParam(example = "desc", value = "排序方式，升序asc还是降序desc") @RequestParam(defaultValue = "desc", required = false) String order) {
        PageInfo<User> userPageInfo = userService.querySelective(schoolName, page, pageSize, sort, order, User.Column.schoolName);
        int size = (int) userPageInfo.getTotal();
        SimplePage simplePage = new SimplePage(size, userPageInfo.getList());
        return ResponseUtil.build(HttpStatus.OK.value(), "搜索用户列表成功！", simplePage);
    }


}
